/*  驱动文件用来驱动设备，device文件用来描述设备
    其实就相当于把普通的驱动程序分成两部分，一部
    分用来存储驱动的数据，一部分用来写open和write
    这种驱动函数
    这个文件中用来描述设备信息
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>

/*操作的led灯的三个引脚的寄存器*/

#define CCM_CCGR1 															0x20C406C	//时钟控制寄存器
#define IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04 				0x20E006C	//GPIO1_04复用功能选择寄存器
#define IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO04 				0x20E02F8	//PAD属性设置寄存器
#define GPIO1_GDIR 															0x0209C004	//GPIO方向设置寄存器（输入或输出）
#define GPIO1_DR 																0x0209C000	//GPIO输出状态寄存器

#define     CCM_CCGR3 							0x020C4074
#define     GPIO4_GDIR 							0x020A8004
#define     GPIO4_DR 							0x020A8000

#define IOMUXC_SW_MUX_CTL_PAD_GPIO4_IO020 			0x020E01E0
#define IOMUXC_SW_PAD_CTL_PAD_GPIO4_IO020 			0x020E046C

#define IOMUXC_SW_MUX_CTL_PAD_GPIO4_IO019 			0x020E01DC
#define IOMUXC_SW_PAD_CTL_PAD_GPIO4_IO019 			0x020E0468


struct resource	rled_resource[]={
	[0] = DEFINE_RES_MEM(GPIO1_DR, 4),
	[1] = DEFINE_RES_MEM(GPIO1_GDIR, 4),
	[2] = DEFINE_RES_MEM(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04, 4),
	[3] = DEFINE_RES_MEM(CCM_CCGR1, 4),
	[4] = DEFINE_RES_MEM(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO04, 4),
};

struct resource	gled_resource[]={
    [0] = DEFINE_RES_MEM(GPIO4_DR, 4),
	[1] = DEFINE_RES_MEM(GPIO4_GDIR, 4),
	[2] = DEFINE_RES_MEM(IOMUXC_SW_MUX_CTL_PAD_GPIO4_IO020, 4),
	[3] = DEFINE_RES_MEM(CCM_CCGR3, 4),
	[4] = DEFINE_RES_MEM(IOMUXC_SW_PAD_CTL_PAD_GPIO4_IO020, 4),
};

struct resource	bled_resource[]={
    [0] = DEFINE_RES_MEM(GPIO4_DR, 4),
	[1] = DEFINE_RES_MEM(GPIO4_GDIR, 4),
	[2] = DEFINE_RES_MEM(IOMUXC_SW_MUX_CTL_PAD_GPIO4_IO019, 4),
	[3] = DEFINE_RES_MEM(CCM_CCGR3, 4),
	[4] = DEFINE_RES_MEM(IOMUXC_SW_PAD_CTL_PAD_GPIO4_IO019, 4),
};

/* led hardware information */
/*记录的其实是寄存器偏移的值*/
unsigned int rled_hwinfo[2] = { 4, 26 };
unsigned int gled_hwinfo[2] = { 20, 12 };
unsigned int bled_hwinfo[2] = { 19, 12 };

void led_release(struct device *dev)
{
	
}

/*看定义就可以指导，resource就是以数组的形式*/
struct platform_device rled_device={
    .name = "gpio_led",
	.id=0,
    .dev ={
        .release = led_release,
        .platform_data = rled_hwinfo,
    },
	.num_resources = ARRAY_SIZE(rled_resource),				/*这个成员用来确定资源数组的大小，使用ARRAY_SIZE函数可以求出来*/
	.resource = rled_resource,
};

struct platform_device gled_device={
	.name = "gpio_led",
	.id = 1,
	.dev ={
		.release = led_release,
		.platform_data = gled_hwinfo,
	},
	.num_resources = ARRAY_SIZE(gled_resource),
	.resource = gled_resource,
};

struct platform_device bled_device={
	.name = "gpio_led",
	.id = 2,
	.dev = {
		.release = led_release,
		.platform_data = bled_hwinfo,
	},
	.num_resources = ARRAY_SIZE(bled_resource),
	.resource = bled_resource,
};

static __init int led_pdev_init(void)
{
	printk("pdev init! \r\n");
	platform_device_register(&rled_device);
	platform_device_register(&gled_device);
	platform_device_register(&bled_device);
	return 0;
}

static __exit void led_pdev_exit(void)
{
	printk("pdev exit!\r\n");
	platform_device_unregister(&rled_device);
	platform_device_unregister(&gled_device);
	platform_device_unregister(&bled_device);
}

module_init(led_pdev_init);
module_exit(led_pdev_exit);
MODULE_AUTHOR("hanyang");
MODULE_LICENSE("GPL");



